commonlibsse_ng\re\m\MemoryManager\alloc\tes_global/
global.rs1use core::alloc::GlobalAlloc;
7use core::ptr;
8use core::{alloc::Layout, hint, ptr::NonNull};
9
10use stdx::alloc::{AllocError, Allocator, non_null_empty_slice};
11
12use crate::re::MemoryManager::alloc::{alloc, dealloc, realloc};
13
14#[derive(Debug, Default, Clone, PartialEq)]
25pub struct TESGlobalAlloc;
26
27unsafe impl Allocator for TESGlobalAlloc {
28 #[inline]
29 #[cfg_attr(miri, track_caller)] fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
31 Self::alloc_impl(layout, false)
32 }
33
34 #[inline]
35 #[cfg_attr(miri, track_caller)] fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
37 Self::alloc_impl(layout, true)
38 }
39
40 #[inline]
41 #[cfg_attr(miri, track_caller)] unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
43 if layout.size() != 0 {
44 unsafe { dealloc(ptr.as_ptr(), layout) }
47 }
48 }
49
50 #[inline]
51 #[cfg_attr(miri, track_caller)] unsafe fn grow(
53 &self,
54 ptr: NonNull<u8>,
55 old_layout: Layout,
56 new_layout: Layout,
57 ) -> Result<NonNull<[u8]>, AllocError> {
58 unsafe { Self::grow_impl(ptr, old_layout, new_layout, false) }
60 }
61
62 #[inline]
63 #[cfg_attr(miri, track_caller)] unsafe fn grow_zeroed(
65 &self,
66 ptr: NonNull<u8>,
67 old_layout: Layout,
68 new_layout: Layout,
69 ) -> Result<NonNull<[u8]>, AllocError> {
70 unsafe { Self::grow_impl(ptr, old_layout, new_layout, true) }
72 }
73
74 #[inline]
75 #[cfg_attr(miri, track_caller)] unsafe fn shrink(
77 &self,
78 ptr: NonNull<u8>,
79 old_layout: Layout,
80 new_layout: Layout,
81 ) -> Result<NonNull<[u8]>, AllocError> {
82 debug_assert!(
83 new_layout.size() <= old_layout.size(),
84 "`new_layout.size()` must be smaller than or equal to `old_layout.size()`"
85 );
86
87 match new_layout.size() {
88 0 => {
90 unsafe { self.deallocate(ptr, old_layout) };
91 Ok(non_null_empty_slice(new_layout))
92 }
93
94 new_size if old_layout.align() == new_layout.align() => unsafe {
96 hint::assert_unchecked(new_size <= old_layout.size());
98
99 let raw_ptr = realloc(ptr.as_ptr(), old_layout, new_size);
100 let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
101 Ok(NonNull::slice_from_raw_parts(ptr, new_size))
102 },
103
104 new_size => unsafe {
110 let new_ptr = self.allocate(new_layout)?;
111 ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.cast().as_ptr(), new_size);
112 self.deallocate(ptr, old_layout);
113 Ok(new_ptr)
114 },
115 }
116 }
117}
118
119unsafe impl GlobalAlloc for TESGlobalAlloc {
120 #[inline]
121 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
122 unsafe { alloc(layout) }
123 }
124
125 #[inline]
126 unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
127 unsafe { dealloc(ptr, layout) }
128 }
129
130 #[inline]
131 unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
132 unsafe { realloc(ptr, layout, new_size) }
133 }
134}